package com.game.rpc;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.lang.reflect.Method;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class ClassInfoGenerater {

	private ArrayList<String> getClassNames() {
		ArrayList<String> list = new ArrayList<String>();
		File file = new File("src/com/game/bean");
		String[] files = file.list(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				return name.indexOf(".java") > 0;
			}
		});
		for (String subFile : files) {
			String name = getName(subFile);
			list.add(name);
		}
		return list;
	}

	public void generateData(ArrayList<String> list) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// factory.setIgnoringElementContentWhitespace(true);
		DocumentBuilder db = factory.newDocumentBuilder();
		Document xmldoc = db.newDocument();
		Element root = xmldoc.createElement("root");
		xmldoc.appendChild(root);

		for (String className : list) {
			Element clsElement = xmldoc.createElement("class");

			clsElement.setAttribute("name", className);

			Class<?> bean = Class.forName("com.game.bean." + className);
			Method[] methods = bean.getMethods();
			for (Method m : methods) {
				String name = m.getName();
				if (name.indexOf("set") == 0 && name.length() > 3
						&& m.getParameterTypes().length == 1) {
					Element fieldElement = xmldoc.createElement("field");
					Class<?> type = m.getParameterTypes()[0];
					String fieldName = name.substring(3);
					fieldElement.setAttribute("name", fieldName);
					String typeName = getClassName(type.getName());
					if (type.isArray()) {
						fieldElement.setAttribute("type1", "ARRAY");
						fieldElement.setAttribute("type2", typeName.substring(0,typeName.length()-1));
					} else {
						fieldElement.setAttribute("type2", "NULL");
						fieldElement.setAttribute("type1", typeName);
					}
					clsElement.appendChild(fieldElement);
				}
			}
			root.appendChild(clsElement);
		}

		TransformerFactory transFactory = TransformerFactory.newInstance();
		Transformer transformer = transFactory.newTransformer();
		transformer.setOutputProperty("encoding", "UTF-8");
		transformer.setOutputProperty("indent", "yes");
		DOMSource source = new DOMSource();
		source.setNode(root);
		StreamResult result = new StreamResult();
		result.setOutputStream(new FileOutputStream("res/info.xml"));
		transformer.transform(source, result);
	}

	private String getClassName(String className) {
		int index = className.lastIndexOf(".");
		if (index > 0) {
			return className.substring(index + 1);
		}
		return className;
	}

	public static void main(String[] args) {
		ClassInfoGenerater generater = new ClassInfoGenerater();
		try {
			generater.generateData(generater.getClassNames());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static String getName(String file) {
		int index = file.indexOf(".");
		if (index > 0) {
			return file.substring(0, index);
		}
		return file;
	}
}
